package com.xqboss.apps.service.sys;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xqboss.apps.domain.sys.SysAnnouncementCategory;
import com.xqboss.apps.domain.sys.SysAnnouncementMsg;
import com.xqboss.apps.dto.system.SysAnnouncementMsgDto;
import com.xqboss.apps.enums.mq.AppMqDelayEnum;
import com.xqboss.apps.enums.sys.FileTypeEnum;
import com.xqboss.apps.enums.sys.PopupJumpEnum;
import com.xqboss.apps.mapper.sys.SysAnnouncementCategoryMapper;
import com.xqboss.apps.mapper.sys.SysAnnouncementMsgMapper;
import com.xqboss.apps.service.aliyun.OssService;
import com.xqboss.apps.vo.sys.SysAnnouncementMsgVo;
import com.xqboss.common.core.domain.entity.SysUser;
import com.xqboss.common.core.mq.MqSender;
import com.xqboss.common.exception.ServiceException;
import com.xqboss.system.mapper.SysUserMapper;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 公告消息表接口
 *
 * @author wangcong
 * @date 2023-08-31
 */
@Service
public class SysAnnouncementMsgService extends ServiceImpl<SysAnnouncementMsgMapper, SysAnnouncementMsg> {

    @Resource
    private SysAnnouncementMsgMapper sysAnnouncementMsgMapper;
    @Resource
    private SysAnnouncementCategoryMapper sysAnnouncementCategoryMapper;
    @Resource
    private SysUserMapper sysUserMapper;
    @Autowired
    private OssService ossService;
    @Lazy
    @Autowired
    private MqSender mqSender;

    /**
     * 添加公告
     *
     * @param msg
     */
    public void addAnnouncementMsg(SysAnnouncementMsg msg) {
        msg.setId(null);
        updateAnnouncementMsg(msg);
    }

    /**
     * 修改公告
     *
     * @param msg
     */
    public void updateAnnouncementMsg(SysAnnouncementMsg msg) {
        LocalDateTime now = LocalDateTime.now();
        if (Objects.nonNull(msg.getSaleableTime())) {
            if (!now.isBefore(msg.getSaleableTime())) {
                throw new ServiceException("上架时间必须为未来时间！");
            }
        }
        if (Objects.nonNull(msg.getRegisterTimeStart()) && Objects.nonNull(msg.getRegisterTimeEnd())) {
            if (!msg.getRegisterTimeStart().isBefore(msg.getRegisterTimeEnd())) {
                throw new ServiceException("结束注册时间必须大于开始注册时间！");
            }
        }
        if (msg.getJumpType() == PopupJumpEnum.H5) {
//            if(Objects.isNull(msg.getOssPath())){
                // 生成path
                String path = FileTypeEnum.AnnouncementHtml.getPath() + IdUtil.fastSimpleUUID() + ".html";
                msg.setOssPath(path);
//            }
            // 将富文本保存到oss
            String link = ossService.putObject(msg.getOssPath(), msg.getContent());
            msg.setJumpContent(link);
        }
        boolean save;
        if (Objects.isNull(msg.getId())) {
            save = save(msg);
        } else {
            save = updateById(msg);
        }
        if (!save) {
            throw new ServiceException("操作失败！");
        }
        // 取消公告消息的延迟消息
        mqSender.cancelDelay(AppMqDelayEnum.ANNO_MSG_SHOW, msg.getId());
        if (Objects.nonNull(msg.getSaleableTime())) {
            mqSender.sendDelay(AppMqDelayEnum.ANNO_MSG_SHOW, msg.getId(), msg.getSaleableTime());
        }
    }

    public List<SysAnnouncementMsg> findBy(SysAnnouncementMsgDto dto) {
        LambdaQueryWrapper<SysAnnouncementMsg> wq = new LambdaQueryWrapper<>();
        if (ObjUtil.isNotNull(dto.getSaleable())) {
            wq.eq(SysAnnouncementMsg::getSaleable, dto.getSaleable());
        }
        if (StrUtil.isNotEmpty(dto.getTitle())) {
            wq.like(SysAnnouncementMsg::getTitle, dto.getTitle());
        }
        wq.orderByDesc(SysAnnouncementMsg::getId);
        List<SysAnnouncementMsg> list = list(wq);
        // 查询出所有分类的名称
        List<SysAnnouncementCategory> categories = sysAnnouncementCategoryMapper.selectList(Wrappers.lambdaQuery(SysAnnouncementCategory.class).select(SysAnnouncementCategory::getId, SysAnnouncementCategory::getCategoryName));
        Map<Long, String> map = categories.stream().collect(Collectors.toMap(SysAnnouncementCategory::getId, SysAnnouncementCategory::getCategoryName));
        list.forEach(e -> {
            if (ObjUtil.isNotEmpty(e.getCategoryId())) {
                e.setCategoryName(map.get(e.getCategoryId()));
            }
        });
        return list;
    }

    public List<SysAnnouncementMsgVo> findByList(SysAnnouncementMsgDto dto) {
        SysUser user = sysUserMapper.selectUserById(dto.getUserId());
        dto.setCreateTime(user.getCreateTime());
        return sysAnnouncementMsgMapper.findByList(dto);
    }

    /**
     * 自动上架公告
     *
     * @param id
     */
    public void autoSaleable(long id) {
        SysAnnouncementMsg msg = getById(id);
        if (Objects.isNull(msg)) {
            throw new ServiceException("公告不存在！");
        }
        if (BooleanUtils.isNotTrue(msg.getSaleable())) {
            //还没有上架， 判断是否达到上架时间
            if (Objects.nonNull(msg.getSaleableTime())) {
                if (LocalDateTime.now().isBefore(msg.getSaleableTime())) {
                    throw new ServiceException("还未到达上架时间！");
                }
            } else {
                throw new ServiceException("未设置自动上架时间！");
            }
        } else {
            throw new ServiceException("重复操作：公告已上架！");
        }
        boolean update = update(new LambdaUpdateWrapper<SysAnnouncementMsg>()
                .set(SysAnnouncementMsg::getSaleable, true)
                .eq(SysAnnouncementMsg::getId, id));
        if (!update) {
            throw new ServiceException("上架失败！");
        }
    }

    /**
     * 获取公告消息
     *
     * @param id
     * @return
     */
    public SysAnnouncementMsg getAnnouncementDetail(Long id) {
        SysAnnouncementMsg msg = getById(id);
        if (msg == null) {
            throw new ServiceException("公告不存在！");
        }
        if (msg.getJumpType() == PopupJumpEnum.H5) {
            // 从oss获取详情
            msg.setContent(ossService.getObject(msg.getOssPath()));
        }
        if (msg.getCategoryId()!=null) {
            SysAnnouncementCategory category = this.sysAnnouncementCategoryMapper.selectById(msg.getCategoryId());
            if (ObjUtil.isNotEmpty(category)) {
                msg.setCategoryName(category.getCategoryName());
            }
        }
        return msg;
    }

    /**
     * 公告上下架
     *
     * @param id
     * @param saleable
     */
    public void changeSaleable(Long id, Boolean saleable) {
        LambdaUpdateWrapper<SysAnnouncementMsg> updateWrapper = new LambdaUpdateWrapper<SysAnnouncementMsg>()
                .set(SysAnnouncementMsg::getSaleable, saleable)
                .eq(SysAnnouncementMsg::getId, id);
        if (saleable) {
            updateWrapper.set(SysAnnouncementMsg::getSaleableTime, LocalDateTime.now());
        }
        boolean update = update(updateWrapper);
        if (!update) {
            throw new ServiceException("操作失败！");
        }
        if (saleable) {
            mqSender.cancelDelay(AppMqDelayEnum.ANNO_MSG_SHOW, id);
        }
    }
}
